package com.example.wxsmart.service.Impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.wxsmart.dto.request.QuestionPageRequest;
import com.example.wxsmart.mapper.QuestionMapper;
import com.example.wxsmart.pojo.Question;
import com.example.wxsmart.resources.RabbitMqListenerResources;
import com.example.wxsmart.service.QuestionService;
import com.example.wxsmart.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author Luojunxian
 * @data 2022/5/30 9:57
 * @classname QuestionServiceImpl
 */
@Slf4j
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

    @Resource
    private RabbitMqListenerResources rabbitMqListenerResources;

    @Resource
    public QuestionMapper questionMapper;

    @CacheEvict(value = "questionList", allEntries = true)
    @Override
    public boolean addOrUpdate(Question question) {
        boolean response = saveOrUpdate(question);

        if (response) {
            rabbitMqListenerResources.sendMessage(Collections.singletonList(question.getId()));
        }

        return response;
    }

    @CacheEvict(value = "questionList", allEntries = true)
    @Override
    public boolean delete(Integer questionId) {
        boolean response = removeById(questionId);
        if (response) {
            rabbitMqListenerResources.sendMessage(Collections.singletonList(questionId));
        }
        return response;
    }

    @CacheEvict(value = "questionList", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addOrUpdateList(List<Question> questionList) {
        boolean response = saveOrUpdateBatch(questionList);

        if (response) {
            CompletableFuture.runAsync(() -> rabbitMqListenerResources.sendMessage(questionList.stream().map(Question::getId).collect(Collectors.toList())));
        }

        return response;
    }

    @Cacheable("questionList")
    @Override
    public IPage<Question> getPagedList(QuestionPageRequest request) {
        return page(new Page<>(request.getPageIndex(), request.getPageSize()), Wrappers.<Question>lambdaQuery()
                .eq(request.getQuestionId() != null, Question::getId, request.getQuestionId())
                .like(StringUtils.isNotBlank(request.getQuestion()), Question::getQuestion, request.getQuestion()));
    }

    @Override
    public List<Question> getQuestionList(List<Integer> idList) {
        List<Question> response = new ArrayList<>();

        if (ObjectUtils.isNotEmpty(idList)) {
            response = questionMapper.selectList(Wrappers.<Question>lambdaQuery().in(Question::getId, idList));
        }

        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void test() {
        // 测试批量更新2千条数据时间
        long begin = System.currentTimeMillis();

        List<Question> save = list();

        save.forEach(this::updateById);

        long end = System.currentTimeMillis();
        String s = TimeUtil.formatHourMinSecondMillisecond(end - begin);
        log.error("更新数据【" + save.size() + "】: " + s);
    }
}
